<template>
  <!-- 搜索框 -->
  <el-card style="height: 120px">
    <el-form :model="queryForm" :inline="true" class="form">
      <el-form-item label="菜品名称:">
        <el-input
            v-model="queryForm.queryName"
            placeholder="请输入菜品名称"
        ></el-input>
      </el-form-item>
      <el-form-item label="菜品状态:">
        <el-select
            v-model="queryForm.status"
            placeholder="请选择菜品状态"
            style="width: 200px"
            clearable
        >
          <el-option label="全部" :value="0"></el-option>
          <el-option label="可售" :value="1"></el-option>
          <el-option label="不可售" :value="2"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="菜品分类:">
        <el-select
            v-model="queryForm.dishCategoryId"
            placeholder="请选择菜品分类"
            style="width: 200px"
            clearable
        >
          <el-option label="全部" :value="0"></el-option>
          <el-option
              v-for="category in dishCategoryList"
              :key="category.dishCategoryId"
              :label="category.name"
              :value="category.dishCategoryId"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="餐厅:">
        <el-select
            v-model="queryForm.restaurantId"
            placeholder="请选择餐厅"
            style="width: 200px"
            clearable
        >
          <el-option label="全部" :value="0"></el-option>
          <el-option
              v-for="category in restaurantList"
              :key="category.restaurantId"
              :label="category.name"
              :value="category.restaurantId"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="default" @click="search">
          搜索
        </el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <!-- 添加菜品和批量删除 -->
  <el-card style="margin: 10px 0">
    <el-tooltip effect="dark" content="添加" placement="top">
      <el-button type="success" size="default" icon="Plus" @click="handleAdd">
      </el-button>
    </el-tooltip>
    <!-- table展示菜品信息 -->
    <el-table style="margin: 10px 0" border :data="dishTableData">
      <el-table-column
          label="菜品名称"
          align="center"
          prop="name"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="菜品描述"
          align="center"
          prop="description"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="菜品价格"
          align="center"
          prop="price"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="菜品库存"
          align="center"
          prop="stock"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="菜品分类"
          align="center"
          prop="dishCategoryName"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="餐厅"
          align="center"
          prop="restaurantName"
          show-overflow-tooltip
      ></el-table-column>
      <el-table-column
          label="菜品图片"
          align="center"
          prop="imageUrl"
          show-overflow-tooltip
      >
        <template #default="{ row }">
          <el-image
              style="width: 100px; height: 100px"
              :preview-src-list="[row.imageUrl]"
              :src="row.imageUrl"
              fit="cover"
          />
        </template>
      </el-table-column>
      <el-table-column
          label="菜品状态"
          align="center"
          prop="status"
          show-overflow-tooltip
          :formatter="(row: any) => {
        const statusMap: Record<number, string> = { 1: '可售', 2: '不可售' };
        return statusMap[row.status] || '未知状态';
      }"
      ></el-table-column>
      <el-table-column label="操作" fixed="right" width="120px" align="center">
        <template #="{ row }">
          <el-tooltip effect="dark" content="编辑" placement="top">
            <el-button
                type="primary"
                size="small"
                icon="Edit"
                @click="handleEdit(row)"
            >
            </el-button>
          </el-tooltip>
          <el-tooltip effect="dark" content="删除" placement="top">
            <el-button
                type="danger"
                size="small"
                icon="Delete"
                @click="handleDelete(row.dishId)"
            >
            </el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="pageSize"
        :page-sizes="[5, 10, 15, 20]"
        :background="true"
        layout="prev, pager, next, jumper,->,sizes,total"
        :total="total"
        @current-change="findAll"
        @size-change="handler"
    />
  </el-card>

  <!-- 抽屉结构:完成添加新的菜品|更新已有的菜品信息 -->
  <el-drawer v-model="drawer" size="1000px">
    <!-- 头部标题:将来文字内容应该动态的 -->
    <template #header>
      <h4>{{ dishForm.dishId ? "更新" : "添加" }}</h4>
    </template>
    <!-- 身体部分 -->
    <template #default>
      <el-form :model="dishForm" :rules="rules" ref="formRef">
        <el-form-item label="菜品名称" prop="name">
          <el-input
              placeholder="请您输入菜品名称"
              v-model="dishForm.name"
          ></el-input>
        </el-form-item>
        <el-form-item label="菜品描述" prop="description">
          <el-input
              placeholder="请您输入菜品描述"
              v-model="dishForm.description"
          ></el-input>
        </el-form-item>
        <el-form-item label="菜品价格" prop="price">
          <el-input
              placeholder="请您输入菜品价格"
              v-model.number="dishForm.price"
              type="number"
              :min="0"
          ></el-input>
        </el-form-item>
        <el-form-item label="菜品库存" prop="stock">
          <el-input
              placeholder="请您输入菜品库存"
              v-model.number="dishForm.stock"
              type="number"
              :min="0"
          ></el-input>
        </el-form-item>
        <el-form-item label="菜品分类" prop="dishCategoryId">
          <el-select
              v-model="dishForm.dishCategoryId"
              placeholder="请选择菜品分类"
              style="width: 200px"
              clearable
          >
            <el-option
                label="请选择菜品分类"
                :value="0"
            ></el-option>
            <el-option
                v-for="category in dishCategoryList"
                :key="category.dishCategoryId"
                :label="category.name"
                :value="category.dishCategoryId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="餐厅信息" prop="restaurantId">
          <el-select
              v-model="dishForm.restaurantId"
              placeholder="请选择餐厅"
              style="width: 200px"
              clearable
          >
            <el-option
                label="请选择餐厅"
                :value="0"
            ></el-option>
            <el-option
                v-for="category in restaurantList"
                :key="category.restaurantId"
                :label="category.name"
                :value="category.restaurantId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="菜品图片" prop="imageUrl">
          <el-upload
              class="upload-demo"
              :show-file-list="false"
              accept=".png,.jpg,.jpeg,.gif"
              drag
              :before-upload="handleBeforeUpload"
              :http-request="handleCustomUploadImage"
              multiple
          >
            <img
                style="width: 200px; height: 200px"
                v-if="dishForm.imageUrl"
                :src="dishForm.imageUrl"
                class="avatar"
                alt="图片"
            />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus/>
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="菜品状态" prop="status">
          <el-select v-model="dishForm.status" placeholder="请选择菜品状态">
            <el-option label="可售" :value="1"></el-option>
            <el-option label="不可售" :value="2"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="drawer = false">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import {ref, reactive, onMounted, nextTick} from "vue";
import {ElFormItem, ElMessage, ElMessageBox} from "element-plus";
import {Plus} from "@element-plus/icons-vue";
import {apiGet, apiPost} from "@/utils/api";
import {validateUtils} from "@/utils/validateUtils";

// 定义菜品分类类型
interface DishCategory {
  dishCategoryId: number;
  name: string;
}

//定义餐厅类型
interface Restaurant {
  restaurantId: number;
  name: string;
}

// 表单数据
let dishForm = reactive({
  dishId: 0,
  name: "",
  description: "",
  price: 0,
  stock: 0,
  imageUrl: "",
  status: 1,
  dishCategoryId: 0,
  restaurantId: 0
});

//搜索表单数据
let queryForm = reactive({
  queryName: "",
  status: 0,
  dishCategoryId: 0,
  restaurantId: 0
});

//默认页码
let pageNo = ref<number>(1);
//一页展示几条数据
let pageSize = ref<number>(5);
//总个数
let total = ref<number>(0);
//存储全部菜品的数组
let dishTableData = ref([]);
//存储菜品分类的数组
let dishCategoryList = ref<DishCategory[]>([]);
//存储餐厅的数组
let restaurantList = ref<Restaurant[]>([]);
//定义响应式数据控制抽屉的显示与隐藏 添加菜品和修改菜品
let drawer = ref<boolean>(false);
//获取form组件实例
let formRef = ref<any>();

//获取全部菜品分类
const fetchAllCategories = async () => {
  let {data} = await apiGet("/dishCategory/findAllCategory");
  dishCategoryList.value = data;
};
//获取全部餐厅信息
const fetchAllRestaurants = async () => {
  let {data} = await apiGet("/restaurant/getAll");
  restaurantList.value = data;
};

//获取全部菜品信息
let findAll = async (pager = 1) => {
  //收集当前页码
  pageNo.value = pager;
  let parameter = {
    page: pageNo.value,
    limit: pageSize.value,
    name: queryForm.queryName,
    status: queryForm.status,
    dishCategoryId: queryForm.dishCategoryId,
    restaurantId: queryForm.restaurantId
  };
  //获取表单数据
  let {data} = await apiGet("/dish/findAll", parameter);
  total.value = data.count;
  dishTableData.value = data.data;
};

//分页器下拉菜单的自定义事件的回调
const handler = () => {
  findAll();
};

//搜索按钮的回调
const search = () => {
  findAll();
};

//添加菜品按钮的回调
const handleAdd = () => {
  //抽屉显示出来
  drawer.value = true;
  //清空dishForm的数据
  Object.assign(dishForm, {
    dishId: 0,
    name: "",
    description: "",
    price: 0,
    stock: 0,
    imageUrl: "",
    status: 1,
    dishCategoryId: 0,
  });
  //清除上一次的错误的提示信息
  nextTick(() => {
    formRef.value.clearValidate();
  });
};

//更新菜品按钮的回调
const handleEdit = (row: any) => {
  //抽屉显示出来
  drawer.value = true;
  //将菜品的信息赋值给dishForm
  Object.assign(dishForm, {
    ...row,
  });
  //清除上一次的错误的提示信息
  nextTick(() => {
    formRef.value.clearValidate();
  });
};

//保存按钮的回调
const save = async () => {
  //点击保存按钮的时候,务必需要保证表单全部复合条件在去发请求
  await formRef.value.validate();
  //保存按钮:添加新的菜品|更新已有的菜品信息
  dishForm.dishId
      ? await apiPost("/dish/edit", {...dishForm})
      : await apiPost("/dish/add", {...dishForm});
  await findAll();
  drawer.value = false;
};

//删除
const handleDelete = async (dishId: number) => {
  //提示用户确认删除吗
  ElMessageBox.confirm("此操作将永久删除该菜品, 是否继续?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(async () => {
        await apiPost("/dish/delete", {dishId});
        await findAll(
            dishTableData.value.length > 1 ? pageNo.value : pageNo.value - 1,
        );
      })
      .catch(() => {
      });
};

//上传文件之前做的一些判断
const handleBeforeUpload = (file: any) => {
  // 检查文件类型 只能上传.png,.jpg,.jpeg,.gif
  const isExcel =
      file.type === "image/png" ||
      file.type === "image/jpg" ||
      file.type === "image/jpeg" ||
      file.type === "image/gif";
  if (!isExcel) {
    ElMessage.error("上传文件只能是.png,.jpg,.jpeg,.gif 格式!");
    return false;
  }

  //上传文件大小不能超过20M
  const isLt20M = file.size / 1024 / 1024 < 20;
  if (!isLt20M) {
    ElMessage.error("上传文件大小不能超过 20MB!");
    return false;
  }
  return isExcel && isLt20M;
};

const handleCustomUploadImage = async (option: any) => {
  const formData = new FormData();
  formData.append("file", option.file);
  let {msg} = await apiPost("/upload/img", formData, {
    headers: {"Content-Type": "multipart/form-data"},
  });
  dishForm.imageUrl = msg;
};

//表单校验的规则对象
const rules = {
  name: [
    {required: true, trigger: "blur", message: "请输入菜品名称"},
    {
      validator: (rule: any, value: string, callback: any) => {
        if (!validateUtils.validateName(value)) {
          callback(new Error("菜品名称长度必须在1到50个字符之间"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  price: [
    {required: true, trigger: "blur", message: "请输入菜品价格"},
    {
      validator: (rule: any, value: number, callback: any) => {
        if (!validateUtils.validatePrice(value)) {
          callback(new Error("价格必须为正数且最多两位小数"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  stock: [
    {required: true, trigger: "blur", message: "请输入菜品库存"},
    {
      validator: (rule: any, value: number, callback: any) => {
        if (!validateUtils.validateStock(value)) {
          callback(new Error("库存必须为非负整数"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  dishCategoryId: [
    {required: true, trigger: "blur", message: "请选择菜品分类"},
    {
      validator: (rule: any, value: number, callback: any) => {
        if (!validateUtils.validateCategoryId(value)) {
          callback(new Error("请选择有效的菜品分类"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  restaurantId: [
    {required: true, trigger: "blur", message: "请选择所属餐厅"},
    {
      validator: (rule: any, value: number, callback: any) => {
        if (!validateUtils.validateRestaurantId(value)) {
          callback(new Error("请选择有效的所属餐厅"));
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
  status: [{required: true, trigger: "blur", message: "请选择菜品状态"}],
};

//组件挂载完毕
onMounted(() => {
  findAll();
  fetchAllCategories();
  fetchAllRestaurants();
});
</script>

<style scoped></style>